package plp.orientadaObjetos2.ambiente;

import plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException;
import plp.orientadaObjetos1.expressao.leftExpression.Id;
import plp.orientadaObjetos1.expressao.valor.Valor;
import plp.orientadaObjetos1.expressao.valor.ValorBooleano;
import plp.orientadaObjetos1.expressao.valor.ValorInteiro;
import plp.orientadaObjetos1.expressao.valor.ValorRef;
import plp.orientadaObjetos1.expressao.valor.ValorString;
import plp.orientadaObjetos1.memoria.colecao.ListaValor;
import plp.orientadaObjetos2.memoria.AmbienteExecucaoOO2;

public class Atributo {

	private String nome;

	private Id idAtributo;

	private String nomeTipoAttributo;

	public Atributo(String nome, String nomeTipoAtributo) {
		this.nome = nome;
		this.nomeTipoAttributo = nomeTipoAtributo;
		this.idAtributo = new Id(this.nome);
	}

	public ValorString getNome(AmbienteExecucaoOO2 ambiente, ListaValor args) {
		return new ValorString(this.nome);
	}

	// TODO: Verificar Valores retornados e levantar excecao adequada
	// No momento se o getter errado for chamado uma ClassCastException sera lancada.
	public Valor getValorObjeto(AmbienteExecucaoOO2 ambiente, ListaValor objeto) throws ObjetoNaoDeclaradoException{
		Valor valor = (ambiente.getObjeto((ValorRef) objeto.getHead())).getEstado().get(this.idAtributo);
		return (ValorRef) valor;
		
	}

	public Valor getValorInteiro(AmbienteExecucaoOO2 ambiente, ListaValor objeto) throws ObjetoNaoDeclaradoException{
		Valor valor = (ambiente.getObjeto((ValorRef) objeto.getHead())).getEstado().get(this.idAtributo);
		return (ValorInteiro) valor;
		
	}

	public Valor getValorBooleano(AmbienteExecucaoOO2 ambiente, ListaValor objeto) throws ObjetoNaoDeclaradoException{
		Valor valor = (ambiente.getObjeto((ValorRef) objeto.getHead())).getEstado().get(this.idAtributo);
		return (ValorBooleano) valor;
		
	}
	
	public Valor getValorString(AmbienteExecucaoOO2 ambiente, ListaValor args) throws ObjetoNaoDeclaradoException{
		Valor valor = (ambiente.getObjeto((ValorRef) args.getHead())).getEstado().get(this.idAtributo);
		return (ValorString) valor;
	}

	public ValorString getNomeTipo(AmbienteExecucaoOO2 ambiente, ListaValor args){
		return new ValorString(this.nomeTipoAttributo);
	}
}
